﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Google.Apis;
using Google.Apis.Util;
using Google.Apis.Tasks.v1;
using Google.Apis.Tasks.v1.Data;


namespace GoogleTasksMigrator
{
    class BiBiCyGTasksManager
    {
        GTasksManager _src_tasks_mgr;
        GTasksManager _dest_tasks_mgr;
        Dictionary<string, string> _tasklists_ids_map;
        Dictionary<string, Dictionary<string, string>> _tasks_ids_map;

        public GTasksManager Src
        {
            get { return _src_tasks_mgr; }
        }
        public GTasksManager Dest
        {
            get { return _dest_tasks_mgr; }
        }

        public BiBiCyGTasksManager()
        {
            _src_tasks_mgr = new GTasksManager();
            _dest_tasks_mgr = new GTasksManager();
            _tasklists_ids_map = new Dictionary<string, string>();
            _tasks_ids_map = new Dictionary<string, Dictionary<string, string>>();
        }

        public TaskList CopyTaskList(TaskList src_list)
        {
            var dest_id = _tasklists_ids_map.GetValueAsNull<string, string>(src_list.Id);
            if (dest_id != null)
            {
                return _dest_tasks_mgr.GetTaskList(dest_id);
            }
            TaskList dest_list = new TaskList
            {
                Title = src_list.Title
            };
            dest_list = _dest_tasks_mgr.InsertList(dest_list);
            _tasklists_ids_map.Add(src_list.Id,dest_list.Id);
            return dest_list;
        }

        /**
         * Copie une tâche, identifiée par sa liste. 
         * La liste doit avoir été déjà copiée (on copie la tâche dans la copie de la liste)
         * La tâche peut avoir été déjà copiée (dans ce ca on ne refait pas la copie).
         * **/
        public Task CopyTask(Task src_task, string src_list_id)
        {   // on vérifie qu'on a une copie de la liste
            string dest_list_id = _tasklists_ids_map.GetValueAsNull<string, string>(src_list_id);
            if (dest_list_id == null)
            {
                throw new Exception(String.Format("Cannot insert task list '{0}' : this list doesn't exist", src_list_id));
            }
            // pour cette liste déjà copiée, quelles tâches ont déjà été copiées ?
            var tasks_map = _tasks_ids_map.GetValueAsNull<string, Dictionary<string, string>>(src_list_id);
            if (tasks_map == null)
            {   // aucune : initialiser le dictionnaire
                _tasks_ids_map.Add(src_list_id, new Dictionary<string, string>());
                tasks_map = _tasks_ids_map[src_list_id];
            }
            else
            {   // a-t-on déjà une copie de la tâche demandée ?
                string dest_task_id = tasks_map.GetValueAsNull<string, string>(src_task.Id);
                if (dest_task_id != null)
                {    // pfuillou, on y arrive !!
                    return _dest_tasks_mgr.GetTask(dest_list_id, dest_task_id);
                }
            }
            // on fait la copie
            Task dest_task = new Task
            {
                Title = src_task.Title,
                Status = src_task.Status,
                Notes = src_task.Notes,
                Due = src_task.Due,
                Completed = src_task.Completed,
                Deleted = src_task.Deleted
            };
            if (src_task.Parent != null)
            {
                var dest_parent = tasks_map.GetValueAsNull<string, string>(src_task.Parent);
                if (dest_parent != null)
                    dest_task.Parent = dest_parent;
            }
            dest_task = _dest_tasks_mgr.InsertTask(dest_task, dest_list_id);
            tasks_map.Add(src_task.Id, dest_task.Id);
            return dest_task;
        }

    }
}
